package graph;

import java.io.FileWriter;
import java.io.IOException;
import java.util.LinkedList;

import geocoding.DistanceCalculator;

import com.keithpower.gekmlib.Placemark;

public class ALGOBusNetNode extends ALGONode {
    protected Placemark myData;
	
    /**
     * default constructor
     */

    public ALGOBusNetNode() {
	super();
		myData = null;
		onClosedList = false;
		onOpenList = false;
		onOptPath = false;
    }

    /**
     * constructor
     *
     * @param id id of this <code>ALGOStringNode</code>
     */

    public ALGOBusNetNode(int id) {
    	super(id);
    	myData = null;
		onClosedList = false;
		onOpenList = false;
		onOptPath = false;
    }

    /**
     * constructor
     *
     * @param id id of this <code>ALGOStringNode</code>
     * @param v value stored in this <code>ALGOStringNode</code>
     */

    public ALGOBusNetNode(int id, Placemark v) {
    	super(id);
    	myData = v;
		onClosedList = false;
		onOpenList = false;
		onOptPath = false;
    }

    /**
     * constructor
     *
     * @param id id of this <code>ALGOStringNode</code>
     * @param c costs of this <code>ALGOStringNode</code>
     * @param v value stored in this <code>ALGOStringNode</code>
     */

    public ALGOBusNetNode(int id, double c, Placemark v) {
    	super(id, c);
    	myData = v;
		onClosedList = false;
		onOpenList = false;
		onOptPath = false;
    }

    /**
     * allows to change the value in this <code>ALGONode</code>
     *
     * @param d <code>int</code> to be stored as the new value
     */

    public void setValue(Placemark d) {
    	myData = d;
    }

    /**
     * returns the value stored in this <code>ALGONode</code>
     *
     * @return <code>int</code> for the stored value
     */

    public Placemark getValue() {
    	return myData;
    }

    /**
     * computes String representation for this <code>ALGONode</code>
     *
     * @return String describing this <code>ALGONode</code>
     */

    public String toString() {
    	return "node(" + new Integer( nodeID ).toString() + "," +
			myData + "," + nodeCost + ")";
    }

    /**
     * creates string representation for GraphViz. 
     * GraphViz is used to visualize <code>ALGOGraph</code>s.
     *
     * @return <code>String</code> representation of this <code>ALGONode</code>
     * according to the syntax of GraphViz
     */

    public String toGraphViz() {
    	return nodeID +
	    	" [color = " + ( isHighlighted ? "red" : "black" ) +
			", label = \"data: " + myData + " cost: " + nodeCost + "\"];";
    }

    /**
     * compares two <code>ALGONode</code>s
     *
     * @param e <code>ALGONode</code> to be compared with this one
     *
     * @return true if they contain identical data; false otherwise
     */

    public boolean equals( Object e ) {
    	if (e == null) return false;
    	else if(e instanceof ALGOBusNetNode) {
    		return ((((ALGOBusNetNode)e).getValue() == myData) &&
    				(nodeID == ((ALGOBusNetNode)e).getNodeID()) &&
					(nodeCost == ((ALGOBusNetNode)e).getNodeCosts()) &&
					(isHighlighted == ((ALGOBusNetNode)e).highlighted()));
    	}
    	else return false;
    }
    
	public boolean isClosed() {
			return onClosedList;
	}
	
	public void putOnClosedList() {
		onClosedList = true;
	}
	
	public void removeFromClosedList() {
		onClosedList = false;
	}
	
	public boolean isOpen() {
			return onOpenList;
	}
	
	public boolean isOnPath() {
		return onOptPath;
	}
	
	public void addToBestPath() {
		onOptPath = true;
	}
	
	public void removeFromBestPath() {
		onOptPath = false;
	}
	
	public void removeFromOpenList() {
		onOpenList = false;
	}
	
	public double costs(ALGOBusNetNode targetNode, SearchableGraph g) {
		double c = 0.0;
		ALGOEdge [] edges = g.getEdgesForNode(this.getNodeID());
		int i;
		
		for (i = 0; i < edges.length; i++) {
			ALGOBusNetNode n = (ALGOBusNetNode)g.getNode(edges[i].getSink());
			if (n.getNodeID() == targetNode.getNodeID()) {
				c = 0.0;
				break;
			}
		}

		if (i == edges.length) c = 1;
		
		return c + 0.75*DistanceCalculator.getDistance(this.getValue().getPoint().getNumericalCoordinates(),
                                                  targetNode.getValue().getPoint().getNumericalCoordinates());
	}
}
